fn main() {
    println!("==========================================");
    test01_count();
    println!("==========================================");
    test02_join_instead_task();
    println!("==========================================");
    test03_other_condition();
    println!("==========================================");
    println!("==========================================");
    test04_channel();
    println!("==========================================");
    test05_one_to_one_channel();
    println!("==========================================");
    test06_multi_to_one_channel();
    println!("==========================================");
}

fn test01_count() {
    use std::time::Duration;
    trpl::run(async {
        let handle = trpl::spawn_task(async {
            for i in 1..10 {
                println!("hi number {i} from the first task!");
                trpl::sleep(Duration::from_millis(500)).await;
            }
        });
        println!("--------------------------------------");
        for i in 1..5 {
            println!("hi number {i} from the second task!");
            trpl::sleep(Duration::from_millis(500)).await;
        }
        println!("--------------------------------------");
        handle.await.unwrap();
        //handle.await.unwrap();
    });
}

fn test02_join_instead_task() {
    use std::time::Duration;
    trpl::run(async {
        let fut1 = async {
            for i in 1..10 {
                println!("hi number {i} from the first task!");
                trpl::sleep(Duration::from_millis(500)).await;
            }
        };
        println!("--------------------------------------");
        let fut2 = async {
            for i in 1..5 {
                println!("hi number {i} from the second task!");
                trpl::sleep(Duration::from_millis(500)).await;
            }
        };
        println!("--------------------------------------");
        trpl::join(fut1, fut2).await;
    });
}

fn test03_other_condition() {
    use std::time::Duration;
    trpl::run(async {
        let fut1 = async {
            for i in 1..10 {
                println!("hi number {i} from the first task!");
                trpl::sleep(Duration::from_millis(500)).await;
            }
        };
        //fut1.await;
        println!("--------------------------------------");
        //let fut2 = async {
        for i in 1..5 {
            println!("hi number {i} from the second task!");
            trpl::sleep(Duration::from_millis(500)).await;
        }
        //};
        //fut2.await;
        println!("--------------------------------------");
        fut1.await;
    });
}

fn test04_channel() {
    trpl::run(async {
        let (tx, mut rx) = trpl::channel();

        let val = String::from("hi");
        tx.send(val).unwrap();

        let received = rx.recv().await.unwrap();
        println!("Got: {received}");
    });
}

fn test05_one_to_one_channel() {
    use std::time::Duration;
    println!("outside");
    trpl::run(async {
        let (tx, mut rx) = trpl::channel();
        let tx_fut = async move {
            let vals = vec![
                String::from("hi"),
                String::from("from"),
                String::from("the"),
                String::from("future"),
            ];
            for val in vals {
                tx.send(val).unwrap();
                trpl::sleep(Duration::from_millis(500)).await;
            }
        };
        let rx_fut = async {
            while let Some(value) = rx.recv().await {
                println!("received '{value}'");
            }
        };
        trpl::join(tx_fut, rx_fut).await;
    });
    println!("outside");
}

fn test06_multi_to_one_channel() {
    use std::time::Duration;
    println!("outside");
    trpl::run(async {
        let (tx, mut rx) = trpl::channel();
        let tx1 = tx.clone();
        let tx_fut = async move {
            let vals = vec![
                String::from("hi"),
                String::from("from"),
                String::from("the"),
                String::from("future"),
            ];
            for val in vals {
                tx.send(val).unwrap();
                trpl::sleep(Duration::from_millis(500)).await;
            }
        };
        let tx1_fut = async move {
            let vals = vec![
                String::from("more"),
                String::from("messages"),
                String::from("for"),
                String::from("you"),
            ];

            for val in vals {
                tx1.send(val).unwrap();
                trpl::sleep(Duration::from_millis(1500)).await;
            }
        };
        let rx_fut = async {
            while let Some(value) = rx.recv().await {
                println!("received '{value}'");
            }
        };
        trpl::join3(tx_fut, tx1_fut, rx_fut).await;
    });
    println!("outside");
}
